﻿using CucumberJwt.Application.Authorization.Jwt.Dto;
using CucumberJwt.Application.Authorization.Jwt.IService;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using System.Linq;

namespace CucumberJwt.Application.Authorization.Jwt.Service
{
    /// <summary>
    /// sdfs
    /// </summary>
   public class JwtAppService: IJwtAppService
    {

        private static ISet<JwtAuthenticateDto> _tokens = new HashSet<JwtAuthenticateDto>();
        private readonly JwtSettings _jwtSettings;

        public JwtAppService(IOptions<JwtSettings> jwtSettingsAccesser)
        {
            _jwtSettings = jwtSettingsAccesser.Value;
        }

        public JwtAuthenticateDto CreateToken()
        {
            DateTime authTime = DateTime.Now;
            DateTime expiresAt = authTime.AddMinutes(_jwtSettings.ExpireMinutes);

            IEnumerable<Claim> claims = new Claim[] {

                new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
                new Claim(JwtRegisteredClaimNames.Iat, $"{new DateTimeOffset(authTime).ToUnixTimeSeconds()}"),
                new Claim(JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(authTime).ToUnixTimeSeconds()}") ,
                //这个就是过期时间，目前是过期100秒，可自定义，注意JWT有自己的缓冲过期时间
                new Claim (JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(expiresAt).ToUnixTimeSeconds()}"),
     
            };
            var identity = new ClaimsIdentity(JwtBearerDefaults.AuthenticationScheme);

            identity.AddClaims(claims);
            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = identity,//创建声明信息
                Issuer = _jwtSettings.Issuer,//Jwt token 的签发者
                Audience = _jwtSettings.Audience,//Jwt token 的接收者
                Expires = expiresAt,//过期时间
                SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtSettings.SecretKey)), SecurityAlgorithms.HmacSha256)//创建 token
            };

            JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
            var token = tokenHandler.CreateToken(tokenDescriptor);


            var jwt = new JwtAuthenticateDto
            {
                Sid= claims.Where(o=>o.Type== JwtRegisteredClaimNames.Jti).FirstOrDefault().Value,
                AuthTime = new DateTimeOffset(authTime).ToUnixTimeSeconds(),
                ExpiresAt = new DateTimeOffset(expiresAt).ToUnixTimeSeconds(),
                Token = tokenHandler.WriteToken(token),
                Success=true
            };
            _tokens.Add(jwt);

            return jwt;
        }
    }
}
